package cn.toma.core.web.interceptor;

import cn.toma.common.utils.web.IPUtil;
import cn.toma.core.annotation.AuthToken;
import cn.toma.core.exception.GlobalException;
import cn.toma.core.result.CodeMsg;
import cn.toma.core.web.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author zqx
 * @version 1.0.0
 * @ClassName AuthenticationInterceptor.java
 * @Description 接口权限拦截器
 * @createTime 2019年09月02日 09:12:00
 */
@Slf4j
@Configuration
public class AuthenticationInterceptor implements HandlerInterceptor
{


	@Autowired
	private RedisTemplate<String, String> redis;

	/**
	 * 请求头参数
	 */
	private static final String AUTHENTICATION = "Authentication";


	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
	{
		// 如果不是方法上的映射则直接通过
		if (!(handler instanceof HandlerMethod)) return true;
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		Method method = handlerMethod.getMethod();
		// 检查是否有要验证的 @AuthToken 注解
		if (!method.isAnnotationPresent(AuthToken.class)) {
			return true;
		}
		else {
			try {
				// 验证token有效性
				String authentication = request.getHeader(AUTHENTICATION);
				String ipAddr = IPUtil.getIpAddr(request);
				String sign = this.redis.opsForValue().get(authentication + "." + ipAddr);
				String username = JWTUtil.getUsername(sign);
				String password = this.redis.opsForValue().get(username + "." + ipAddr);
				boolean verify = JWTUtil.verify(sign, username, password);
				if (!verify) {
					throw new GlobalException(CodeMsg.UNAUTHORIZED);
				}
				return true;
			} catch (Exception e) {
				throw new GlobalException(CodeMsg.UNAUTHORIZED);
			}

		}
	}


	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
	{

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
	{

	}
}
